#ifndef dq_PersistenceController_h
#define dq_PersistenceController_h

#include "DeclareList.h"
#include <utility/String.h>
#include <utility/EventHandler.h>
#include <vector>

namespace serika
{
	namespace dq
	{
		class Item;

		class PersistenceController : public ut::EventHandler
		{
		public:
			PersistenceController();
			~PersistenceController();

			virtual void Handle(const ut::Event& e);

			void Search(const ut::String& name, Items& items);
			void Search(int itemType, Items& items);

		private:
			void OnUiEvent(const ut::Event& e);
			void OnPersistenceEvent(const ut::Event& e);

			void OnRequestNewItem(const ut::Event& e);
			void OnRequestPropertyTemplates(const ut::Event& e);
			void OnItemTabInit(const ut::Event& e);
			void OnCreateItem(const ut::Event& e);
			void OnSaveItem(const ut::Event& e);
			void OnRequestItemCategories(const ut::Event& e);
			void OnRequestItemList(const ut::Event& e);
			void OnRequestTownList(const ut::Event& e);
			void OnRequestItemProperties(const ut::Event& e);
			void OnRequestAlchemyList(const ut::Event& e);

			void OnRequestProduct(const ut::Event& e);
			void OnRequestMaterial1(const ut::Event& e);
			void OnRequestMaterial2(const ut::Event& e);
			void OnRequestMaterial3(const ut::Event& e);

		private:
			Item* NewItem();
			const PropertyTemplates& GetPropertyTemplates(int itemType);
			const ItemCategories& GetItemCategories(int itemType);
			void GetItems(int itemType, Items& items);
			const Items& GetAllItems();
			Item* GetItem(int id);
			const Towns& GetTowns();
			const Alchemies& GetAlchemies();
			void GenItemProperties(const Items& items);
			void GenItemProperties(Item* item);

		private:
			template<class Type, class DbType>
			void GetAllTwoType(std::vector<Type*>& types, const ut::String& ids = _T(""));
			template<class DbType>
			void GetAllOneType(std::vector<DbType*>& dbs, const ut::String& ids = _T(""));
			template<class Type, class DbType>
			void ToTransient(std::vector<Type*>& types, const std::vector<DbType*>& dbs);
			template<class Type>
			void Save(const std::vector<Type*>& types);
			template<class Type>
			void Delete(const std::vector<Type*>& types);

		private:
			bool mHasReadItems;
		};
	}
}

#endif
